﻿using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using CanvasControl.Model;
using CanvasControl.View;

namespace CanvasControl.Interface
{
    public class CanvasController
    {
        /// <summary>
        /// Экземпляр представления.
        /// </summary>
        readonly ICanvasView view;

        /// <summary>
        /// Список поведений.
        /// </summary>
        readonly List<ICanvasBehavior> behaviors = new List<ICanvasBehavior>();

        public CanvasModel Model { get; set; }

        public CanvasController(ICanvasView view)
        {
            this.view = view;
            Model = new CanvasModel();
        }

        public void AddBehavior(ICanvasBehavior behavior)
        {
            behaviors.Add(behavior);
            behavior.Install(view, Model);
        }

        public void RemoveBehavior(ICanvasBehavior behavior)
        {
            behaviors.Remove(behavior);
            behavior.Uninstall(Model);
        }

        public void OnMouseDown(Point p, Keys keys, MouseButtons buttons)
        {
            var viewPoint = Model.ViewPort.ClientToGlobal(p);
            var input = new InputState(viewPoint, p, keys, buttons);
            foreach (var listener in Model.GetListeners())
                listener.OnMouseDown(input);
        }

        public void OnMouseMove(Point p)
        {
            foreach (var listener in Model.GetListeners())
                listener.OnMouseMove(p);
        }
        
        public void OnMouseUp(Point p)
        {
            foreach (var listener in Model.GetListeners())
                listener.OnMouseUp(p);
            view.UpdateView();
        }

        public void OnMouseWheel(int delta)
        {
            if (delta == 0)
                return;
            if (delta > 0)
                Model.ViewPort.ZoomIn();
            else
                Model.ViewPort.ZoomOut();
            view.UpdateView();
        }

        public void OnSizeChanged(Size size)
        {
            Model.ViewPort.Resize(size);
            view.UpdateView();
        }

        /// <summary>
        /// Вызывает отрисовку фона.   
        /// </summary>
        /// <param name="context">Контекст рисования.</param>
        public void DrawBackground(DrawingContext context)
        {
            var painters = Model.GetStagePainters(PaintStages.BACKGROUND);
            foreach (var painter in painters)
                painter.Draw(context);
        }

        /// <summary>
        /// Вызывает отрисовку содержимого.
        /// </summary>
        /// <param name="context">Контекст рисования.</param>
        public void DrawOther(DrawingContext context)
        {
            var painters = Model.GetStagePainters(PaintStages.CONTENT);
            foreach (var painter in painters)
                painter.Draw(context);
            painters = Model.GetStagePainters(PaintStages.POSTPROCESSING);
            foreach (var painter in painters)
                painter.Draw(context);
        }
    }
}